package com.qf.leadnewsarticle.api;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qf.leadnewsarticle.service.ArticleService;
import com.qf.qfleadnewsfeignapi.article.ArticleApi;
import com.qf.qfleadnewsfeignapi.wemedia.WeMediaApi;
import com.qf.qfleadnewsmodel.article.pojos.ApArticle;
import com.qf.qfleadnewsmodel.article.vos.ApArticleVo;
import com.qf.qfleadnewsmodel.commons.consts.RedisConst;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RestController;

import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@RestController
public class ArticleFeignApi implements ArticleApi {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private ArticleService articleService;

    @Autowired
    private WeMediaApi weMediaApi;

    @Override
    public void computeHot() {
        //获取过去7天的数据
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DAY_OF_MONTH,-7);
        Date last7DayTime = instance.getTime();
        Wrapper<ApArticle> qw = Wrappers.lambdaQuery(ApArticle.class)
                .ge(ApArticle::getPublishTime,last7DayTime);
        List<ApArticle> articles = articleService.list(qw);

        //全频道缓存
        cacheHotToChannal(articles,null);

        //todo: 根据不同频道分别缓存对应频道的热点数据
        List<Integer> channelIds = weMediaApi.getChannelIds();
        channelIds.forEach(channelId->{
            List<ApArticle> apArticleList = articleService.list(Wrappers.lambdaQuery(ApArticle.class)
                    .eq(ApArticle::getChannelId, channelId)
                    .ge(ApArticle::getPublishTime, last7DayTime));

            cacheHotToChannal(apArticleList,channelId);
        });
    }

    private void cacheHotToChannal(List<ApArticle> articles,Integer channelId) {
        if (articles != null){
            List<ApArticleVo> apArticleVos = articles.stream().map(article -> {
                //文章id
                Long id = article.getId();

                try(RedisConnection conn = redisTemplate.getConnectionFactory().getConnection()){
                    //获取文章的阅读数、点赞数、收藏数

                    byte[] key = (RedisConst.ARTICLE_READ_PREFIX + id).getBytes(StandardCharsets.UTF_8);
                    Long readCount = conn.bitCount(key);

                    key = (RedisConst.ARTICLE_LIKE_PREFIX + id).getBytes(StandardCharsets.UTF_8);
                    Long likeCount = conn.bitCount(key);

                    key = (RedisConst.ARTICLE_COLLECTION_PREFIX + id).getBytes(StandardCharsets.UTF_8);
                    Long collectionCount = conn.bitCount(key);

                    //计算文章热度分值
                    long totalScore = 0;
                    totalScore += readCount * RedisConst.BEHAVIOR_READ_WEIGHT;
                    totalScore += likeCount * RedisConst.BEHAVIOR_LIKE_WEIGHT;
                    totalScore += collectionCount * RedisConst.BEHAVIOR_COLLECTION_WEIGHT;

                    ApArticleVo apArticleVo = new ApArticleVo();
                    BeanUtils.copyProperties(article, apArticleVo);
                    apArticleVo.setScore(totalScore);

                    return apArticleVo;
                }catch (Exception e){
                    e.printStackTrace();
                    return null;
                }
            }).sorted().limit(30).collect(Collectors.toList());


            //将得到的热点数据缓存到redis
            String apArticleVosJson = JSON.toJSONString(apArticleVos);

            //根据不同频道，分别缓存不频道的热点数据
            if (channelId == null) {
                String key = RedisConst.ARTICLE_HOT_CACHE_PREFIX + "__all__";
                redisTemplate.opsForValue().set(key, apArticleVosJson);
            }else{
                String key = RedisConst.ARTICLE_HOT_CACHE_PREFIX + channelId;
                redisTemplate.opsForValue().set(key, apArticleVosJson);
            }
        }
    }

    public static void main(String[] args) {
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.DAY_OF_MONTH,-37);
        System.out.println(instance.getTime());
    }
}
